package com.ctshk.rpc.finance.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.*;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.utils.CharUtil;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.common.utils.SnowflakeIdWorker;
import com.ctshk.rpc.finance.dto.bill.BillConfirmDTO;
import com.ctshk.rpc.finance.entity.FinanceBill;
import com.ctshk.rpc.finance.entity.FinanceBillConfirm;
import com.ctshk.rpc.finance.json.ConfirmAmountJson;
import com.ctshk.rpc.finance.json.FileJson;
import com.ctshk.rpc.finance.mapper.FinanceBillConfirmMapper;
import com.ctshk.rpc.finance.mapper.FinanceBillMapper;
import com.ctshk.rpc.finance.req.bill.BillConfirmAddReq;
import com.ctshk.rpc.finance.req.bill.BillConfirmIdReq;
import com.ctshk.rpc.finance.req.bill.RollBackReq;
import com.ctshk.rpc.finance.req.supplier.AprovalReq;
import com.ctshk.rpc.finance.service.IFinanceBillConfirmService;
import com.ctshk.rpc.order.air.req.ReceivePaymentConfirmReq;
import com.ctshk.rpc.order.air.service.IAirOrderService;
import com.ctshk.rpc.order.custom.service.ICustomizedOrderCollectionService;
import com.ctshk.rpc.order.scenic.req.ScenicOrderCollectionRejectReq;
import com.ctshk.rpc.order.scenic.service.IScenicOrderCollectionService;
import com.ctshk.rpc.order.tour.service.ISeriesOrderCollectionService;
import com.ctshk.rpc.system.dto.UserDTO;
import com.ctshk.rpc.system.service.ISysUserService;
import com.ctshk.rpc.workflow.dto.ApprovalCheckDTO;
import com.ctshk.rpc.workflow.dto.ApprovalStartDTO;
import com.ctshk.rpc.workflow.service.ISysApprovalService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 财务认款 服务实现类
 * </p>
 *
 * @author 叶冠峰
 * @since 2021-03-26
 */
@DubboService
public class FinanceBillConfirmServiceImpl extends ServiceImpl<FinanceBillConfirmMapper, FinanceBillConfirm> implements IFinanceBillConfirmService {

    @Autowired
    private FinanceBillConfirmMapper billConfirmMapper;
    @Autowired
    private FinanceBillMapper billMapper;

    /*@Autowired
    private RedisTemplate<String, Object> redisTemplate;*/

    @DubboReference
    private ISysApprovalService sysApprovalService;
    @DubboReference
    private ISysUserService sysUserService;
    @DubboReference
    private IAirOrderService airOrderService;
    @DubboReference
    private ICustomizedOrderCollectionService customizedOrderCollectionService;
    @DubboReference
    private IScenicOrderCollectionService scenicOrderCollectionService;
    @DubboReference
    private ISeriesOrderCollectionService seriesOrderCollectionService;



    /**
     * 提交审批
     *
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result add(BillConfirmAddReq req) {
        //过滤不符合认款条件的ID
        if (req.getIdList().size() == 0){
            throw new BusinessException(SystemError.SYS_409,"idList");
        }
        List<Long> idList = new ArrayList<>();
        List<FinanceBill> billList = billMapper.selectBatchIds(req.getIdList());
        if (billList != null && billList.size() > 0){
            billList.forEach(bill -> {
                if (Objects.equals(bill.getBillType(),1) && bill.getConfirmId() == null && Objects.equals(bill.getIsDeleted(),0)){
                    idList.add(bill.getId());
                }
            });
        }
        if (idList.size() == 0){
            throw new BusinessException(SystemError.FINANCE_BILL_17008);
        }
        //新增认款记录
        FinanceBillConfirm confirm = new FinanceBillConfirm();
        confirm.setId(SnowflakeIdWorker.nextId());
        //认款金额
        BigDecimal confirmAmount = billMapper.sumCollectionAmountByBatchId(idList);
        if (confirmAmount == null){
            confirmAmount = BigDecimal.ZERO;
        }
        confirm.setConfirmAmount(confirmAmount);
        if (CollectionUtils.isNotEmpty(req.getAmountList())){
            confirm.setConfirmAmountJson(JSON.toJSONString(req.getAmountList()));
        }
        confirm.setConfirmStatus(2);
        confirm.setConfirmUserId(req.getUserId());
        UserDTO userDto = sysUserService.queryCacheUser(req.getUserId());
        if (userDto != null){
            confirm.setConfirmUserName(userDto.getFullName());
        }
        LocalDateTime now = LocalDateTime.now();
        confirm.setConfirmTime(now);
        confirm.setConfirmServiceCharge(req.getConfirmServiceCharge());
        confirm.setConfirmServiceChargeCurrencyId(req.getCurrencyId());
        confirm.setConfirmServiceChargeCurrencyName(req.getCurrency());
        if (req.getVoucherJsonList() != null && req.getVoucherJsonList().size() > 0){
            String voucherJson = JSONArray.toJSONString(req.getVoucherJsonList());
            confirm.setConfirmVoucherJson(voucherJson);
        }
        confirm.setConfirmRemark(req.getConfirmRemark());
        confirm.setGmtCreate(now);
        confirm.setCreateId(req.getUserId());
        confirm.setIsDeleted(0);
        boolean save = save(confirm);
        //批量关联认款单
        Integer batch = billMapper.batchUpdateConfirmId(confirm.getId(),req.getUserId(),idList);
        if (!save || batch < idList.size()){
            throw new BusinessException(SystemError.SYS_437);
        }
        //发起审批
        Long approvalId = startApproval(confirm.getId(), confirm.getId(), req.getUserId(),confirm.getConfirmAmount());
        confirm.setApprovalId(approvalId);
        boolean update = updateById(confirm);
        if (!update){
            throw new BusinessException(SystemError.SYS_437);
        }
        return Result.success(confirm.getId());
    }

    /**
     * 认款信息
     *
     * @param req
     * @return
     */
    @Override
    public Result<BillConfirmDTO> detail(BillConfirmIdReq req) {
        FinanceBillConfirm confirm = getById(req.getConfirmId());
        if (confirm == null || Objects.equals(confirm.getIsDeleted(),1)){
            throw new BusinessException(SystemError.FINANCE_BILL_17009);
        }
        BillConfirmDTO dto = EntityUtil.copy(confirm, BillConfirmDTO.class);
        //认款人
        UserDTO userDto = sysUserService.queryCacheUser(confirm.getConfirmUserId());
        if (userDto != null){
            dto.setConfirmUserDept(userDto.getDept());
        }
        if (StringUtils.isNotBlank(confirm.getConfirmAmountJson())){
            List<ConfirmAmountJson> amountJsonList = JSON.parseArray(confirm.getConfirmAmountJson(), ConfirmAmountJson.class);
            dto.setAmountList(amountJsonList);
        }
        //附件
        if (StringUtils.isNotBlank(confirm.getConfirmVoucherJson())){
            List<FileJson> fileJsons = JSON.parseArray(confirm.getConfirmVoucherJson(), FileJson.class);
            dto.setConfirmVoucherJson(fileJsons);
        }
        return Result.success(dto);
    }

    /**
     * 审批
     *
     * @param req
     * @param currentUser
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result approval(AprovalReq req, TokenUser currentUser) {
        QueryWrapper<FinanceBillConfirm> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("approval_id",req.getId());
        queryWrapper.eq("is_deleted",0);
        FinanceBillConfirm confirm = billConfirmMapper.selectOne(queryWrapper);
        if (confirm == null){
            throw new BusinessException(SystemError.FINANCE_BILL_17009);
        }
        if (!Objects.equals(confirm.getConfirmStatus(),2)){
            throw new BusinessException(SystemError.FINANCE_BILL_17012);
        }
        confirm.setModifiedId(req.getUserId());
        confirm.setConfirmStatus(req.getType());
        confirm.setConfirmStatus(req.getType());
        if (Objects.equals(req.getType(),3)){
            //审批通过
            confirm.setConfirmTime(LocalDateTime.now());
        }
        boolean update = updateById(confirm);
        if (!update){
            throw new BusinessException(SystemError.SYS_437);
        }
        Result<ApprovalCheckDTO> check = sysApprovalService.check(req.getId(), req.getUserId(), req.getType(), req.getComments());
        if (check == null || !check.getData().getIsFinish()){
            throw new BusinessException(SystemError.SYS_437);
        }
        return Result.success(confirm.getId());
    }

    /**
     * 撤回审批
     *
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result rollBack(RollBackReq req) {
        QueryWrapper<FinanceBillConfirm> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("approval_id",req.getApprovalId());
        queryWrapper.eq("is_deleted",0);
        FinanceBillConfirm confirm = billConfirmMapper.selectOne(queryWrapper);
        if (confirm == null){
            throw new BusinessException(SystemError.FINANCE_BILL_17009);
        }
        if (!Objects.equals(confirm.getCreateId(),req.getUserId())){
            throw new BusinessException(SystemError.FINANCE_ERROR_17039);
        }
        //删除认款记录
        confirm.setIsDeleted(1);
        confirm.setModifiedId(req.getUserId());
        int del = billConfirmMapper.updateById(confirm);
        //恢复认款单状态
        QueryWrapper<FinanceBill> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("confirm_id",confirm.getId());
        queryWrapper1.eq("is_deleted",0);
        FinanceBill bill = billMapper.selectOne(queryWrapper1);
        if (bill == null){
            throw new BusinessException(SystemError.FINANCE_BILL_17009);
        }
        bill.setConfirmId(null);
        bill.setCheckBillStatus(0);
        bill.setModifiedId(req.getUserId());
        int update = billMapper.updateById(bill);
        if (del <= 0 || update <= 0){
            throw new BusinessException(SystemError.SYS_437);
        }
        Result<ApprovalCheckDTO> check = sysApprovalService.check(req.getApprovalId(), req.getUserId(), 0, null);
        if (check == null || !check.getData().getIsFinish()){
            throw new BusinessException(SystemError.SYS_437);
        }
        return Result.success();
    }

    /**
     * 发起审批流程
     * @param id
     * @param businessId
     * @param userId
     */
    private Long startApproval(Long id, Long businessId, Long userId,BigDecimal amount) {
        Map<String, Object> extendParams = new HashMap<>();
        extendParams.put("id", id);
        try{
            Result<ApprovalStartDTO> approvalResult = sysApprovalService.start(SystemBusinessType.FINANCE.getCode(),
                    SysApprovalType.RECOGNITION_FINANCE.getCode(), businessId,
                    userId, amount, JSON.toJSONString(extendParams));
            if (!approvalResult.isSuccess()) {
                throw new BusinessException(SystemError.CUSTOM_ORDER_4044);
            }
            return approvalResult.getData().getApprovalId();
        }catch (Exception e){
            throw new BusinessException(SystemError.SYS_422);
        }
    }


}
